package com.zxjia.ssmp.service.impl;

import com.alibaba.fastjson.JSON;
import com.zxjia.ssmp.doc.ProductDoc;
import com.zxjia.ssmp.dto.CartRequest;
import com.zxjia.ssmp.dto.AppIndexRequest;
import com.zxjia.ssmp.dto.ProductRequest;
import com.zxjia.ssmp.exception.BusinessException;
import com.zxjia.ssmp.api.ProductApiService;
import com.zxjia.ssmp.service.ProductService;
import com.zxjia.ssmp.vo.IndexVo;
import com.zxjia.ssmp.vo.ProductCateVo;
import com.zxjia.ssmp.vo.ProductImageVo;
import com.zxjia.ssmp.vo.ProductVo;
import lombok.val;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.AnalyzeRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    ProductApiService productApiService;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public List<ProductCateVo> list() {
        return productApiService.getProductCate();
    }

    @Override
    public IndexVo getProductCateById(ProductRequest request) {
        IndexVo indexVo = new IndexVo();
        indexVo.setProductVoList(productApiService.getProductByCatId(request));
        return indexVo;
    }

    @Override
    public IndexVo search(AppIndexRequest request) {

        IndexVo indexVo = new IndexVo();

        try {

            SearchRequest searchRequest = new SearchRequest("product_index");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            //AnalyzeRequest
            MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("productName", request.getSearch());

            sourceBuilder.query(termQueryBuilder);
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

            searchRequest.source(sourceBuilder);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            List<ProductVo> productVoList = new ArrayList<>();
            for (SearchHit hit : searchResponse.getHits().getHits()) {
                productVoList.add(JSON.parseObject(hit.getSourceAsString(),ProductVo.class));
            }

            indexVo.setProductVoList(productVoList);
        } catch (Exception e) {

        }

        return indexVo;
    }

    @Override
    public boolean updateProduct(ProductRequest request) {
        return productApiService.updateProduct(request);
    }

    @Override
    public void saveAll() {
        List<ProductVo> productVoList = findAll();

        List<ProductDoc> productDocList = new ArrayList<>();
        productVoList.stream().forEach(e -> {
            ProductDoc productDoc = new ProductDoc();
            BeanUtils.copyProperties( e, productDoc);
            productDocList.add(productDoc);
        });

        val bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        for (int i=0; i< productVoList.size(); i++) {
            bulkRequest.add(new IndexRequest("product_index")
                    .source(JSON.toJSONString(productVoList.get(i)), XContentType.JSON));
        }
        try {
            BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println(bulk.hasFailures());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<ProductVo> getProductByCateId(ProductRequest request) {
        return productApiService.getProductByCatId(request);
    }

    @Override
    public List<ProductImageVo> getProductImageById(Integer productId) {
        return productApiService.getProductImageById(productId);
    }

    @Override
    public List<ProductVo> findAll() {
        return productApiService.findAll();
    }

    @Override
    public ProductVo getProductById(ProductRequest request) {
        ProductVo productVo = productApiService.getProductById(request.getProductId());
        if(productVo == null) {
            throw new BusinessException("商品未找到");
        }
        List<ProductImageVo> productImageVos = getProductImageById(productVo.getId());
        productVo.setProductImageVos(productImageVos);
        return productVo;
    }

    @Override
    public List<ProductVo> getProductByIds(ProductRequest request) {
        return productApiService.getProductByIds(request);
    }


    @Override
    public boolean addCart(CartRequest request) {
        return productApiService.addCart(request);
    }



}
